unit TypeTest;

interface

uses
   Db
  ,SysUtils
  ;

type

  ITypeTest = interface
  ['{EB1CF3B9-4981-423E-9DEC-5F650B8A3D41}']
    function DateTimeStrToDateTime( Data: string; out Value: TDateTime ): boolean;
    function IntegerStrToInt( Data: string; out Value: Integer ): boolean;
    function FloatStrToFloat( Data: string; out Value: Extended ): boolean;
    function FieldTypeTest( Const Data: String ):TFieldType;
    end;

  TTypeTest = class( TInterfacedObject, ITypeTest )
  public
    //See note above implementation..
    function DateTimeStrToDateTime( Data: string; out Value: TDateTime ): boolean;
    function IntegerStrToInt( Data: string; out Value: Integer ): boolean;
    function FloatStrToFloat( Data: string; out Value: Extended ): boolean;
    function FieldTypeTest( Const Data: String ):TFieldType;
    end;

implementation

{ TTypeTest }


{
   DateTimeStr format is assumed to YYYY/MM/DD HH:MM:SS or YYY/MM/DD,
   eg "2011/05/28 17:15:05", "2011/05/28"
   Any other format will be result in a return value of False.
}
function TTypeTest.DateTimeStrToDateTime(Data: string;
  out Value: TDateTime): boolean;
  type
  TElement = ( eYear, eMonth, eDay, eHours, eMinutes, eSeconds, eEof );

  var
  str_element: string;
  len: integer;
  counter: integer;
  phase : TElement;
  date_time_element: array[ eYear..eSeconds ] of word;
  temp_result: extended;
  begin
  Data := Trim( Data );
  str_element := '';
  len := length( Data );
  for phase := eYear to eEof do  date_time_element[ phase ] := 0;
  phase := eYear;
  counter := 1;
  Result := True;
  try
    while counter <= len do
      begin
      if phase in [ eYear..eDay ] then
        begin
        if Data[ counter ] in [ '/', ' ' ] then
          begin
          date_time_element[ phase ] := StrToInt( str_element );
          inc( phase );
          str_element := '';
          end
        else
          str_element := str_element + Data[ counter ];
        end
      else if phase in [ eHours..eSeconds ] then
        begin
        if ( Data[ counter ] = ':' ) then
          begin
          date_time_element[ phase ] := StrToInt( str_element );
          inc( phase );
          str_element := '';
          end
        else
          str_element := str_element + Data[ counter ];
        end;
      inc( counter );
      end;
    date_time_element[ phase ] := StrToInt( str_element );
    Value := EncodeDate( date_time_element[ eYear ], date_time_element[ eMonth ], date_time_element[ eDay ] );
    temp_result := ( date_time_element[ eHours ] + date_time_element[ eMinutes ]/60 + date_time_element[ eSeconds ]/3600 )/24;
    Value := Value + temp_result;
  except
    Result := False;
    end;
  end;

function TTypeTest.FieldTypeTest(const Data: String): TFieldType;
  var
  i: integer;
  f: extended;
  d: TDateTime;
  begin
  if DateTimeStrToDateTime( Data, d ) then
    Result := ftDateTime
  else if IntegerStrToInt( Data, i ) then
    Result := ftInteger
  else if FloatStrToFloat( Data, f ) then
    Result := ftFloat
  else
    Result := ftString;
  end;

function TTypeTest.FloatStrToFloat(Data: string; out Value: Extended): boolean;
  begin
  try
    Result := True;
    StrToFloat( Data );
  except
    Result := False;
    end;
  end;

function TTypeTest.IntegerStrToInt(Data: string; out Value: Integer): boolean;
  begin
  try
    Result := True;
    Value := StrToInt( Data );
  except
    Result := False;
    end;
  end;


end.
